﻿using Liang.Device.Camera.Dll;
using Liang.Device.Model.Camera;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Liang.Device.Camera.Action
{
    /// <summary>
    /// 海康威视摄像头DLL
    /// </summary>
    public sealed class HikVisionCamera : ICamera<HikVision>
    {
        private static readonly HikVisionCamera _instance = new HikVisionCamera();

        public static HikVisionCamera Instance
        {
            get { return _instance; }
        }

        /// <summary>
        /// 判断摄像头是否已初始化SDK
        /// </summary>
        /// 
        private static bool isSDKInited = false;

        /// <summary>
        /// SDK是否已初始化
        /// </summary>
        public static bool IsSDKInited
        {
            get { return HikVisionCamera.isSDKInited; }
            set { HikVisionCamera.isSDKInited = value; }
        }

        static HikVisionCamera()
        {
            try
            {
                HikVisionCamera.IsSDKInited = HikVisionDll.KsCamera_HC_InitSDK();
            }
            catch (Exception e)
            {
                throw new CameraException("无法初始化海康摄像头SDK", e.Message);
            }
        }

        private HikVisionCamera()
        {

        }

        ~HikVisionCamera()
        {
            if (IsSDKInited)
            {
                try
                {
                    HikVisionDll.KsCamera_HC_CleanupSDK();
                }
                catch (Exception e)
                {
                    throw new CameraException("无法注销海康摄像头SDK", e.Message);
                }
            }
        }

        public bool Open(HikVision cameraParam)
        {
            try
            {
                cameraParam.LoginId = HikVisionDll.KsCamera_HC_Login(cameraParam.PlayWindow, cameraParam.Ipaddr, (short)cameraParam.Port, cameraParam.Accesscout, cameraParam.Password);

                if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw new CameraException("无法登陆摄像头", e.Message);
            }

            return true;
        }

        public bool Play(HikVision cameraParam)
        {
            if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
            {
                return false;
            }

            bool bSuccessed = false;

            try
            {
                bSuccessed = HikVisionDll.KsCamera_HC_RealPlay(cameraParam.LoginId, cameraParam.Channel);
            }
            catch (Exception e)
            {
                throw new CameraException("无法播放视频", e.Message);
            }

            return bSuccessed;
        }

        public bool Stop(HikVision cameraParam)
        {
            try
            {
                HikVisionDll.KsCamera_HC_StopPlay(cameraParam.LoginId);
            }
            catch (Exception e)
            {
                throw new CameraException("无法停止播放", e.Message);
            }

            return true;
        }

        public bool Close(HikVision cameraParam)
        {
            try
            {
                HikVisionDll.KsCamera_HC_Logout(cameraParam.LoginId);
                cameraParam.LoginId = 0;
            }
            catch (Exception e)
            {
                throw new CameraException("无法关闭摄像头", e.Message);
            }

            return true;
        }

        public bool Capture(HikVision cameraParam, string strImageFile)
        {
            if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
            {
                return false;
            }

            bool bSuccessed = false;

            try
            {
                bSuccessed = HikVisionDll.KsCamera_HC_CaptureImage(cameraParam.LoginId, strImageFile);
            }
            catch (Exception e)
            {
                throw new CameraException("摄像头抓拍失败", e.Message);
            }

            return bSuccessed;
        }

        /// <summary>
        /// 注册IO报警
        /// </summary>
        /// <param name="obj">摄像头参数</param>
        /// <param name="alarmWindow">报警消息通知窗口句柄</param>
        /// <param name="alarmMessage">报警消息</param>
        /// <param name="imageSavePath">IO报警抓拍图片存储路径</param>
        /// <returns></returns>
        /// <example>
        /// 注册IO报警抓拍，并启用IO抓拍后，SDK会在后台抓拍图片到指定的目录，并通过消息通知主程序，主程序通过从消息的WParam参数获取图片数据id，然后调用GetIOAlarmCaptureImage获取数据
        /// </example>
        public bool SetIOAlarmCapture(HikVision cameraParam, IntPtr alarmWindow, uint alarmMessage, string imageSavePath)
        {
            if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
            {
                return false;
            }

            bool result = false;
            try
            {
                result = HikVisionDll.KsCamera_HC_SetIOAlarmCapture(alarmWindow, alarmMessage, imageSavePath);
            }
            catch (Exception e)
            {
                throw new CameraException("注册IO报警抓拍失败", e.Message);
            }

            return result;
        }

        /// <summary>
        /// IO报警使能
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="enable">是否启用IO报警抓拍</param>
        /// <param name="newAlarm">报警类型（新、旧）</param>
        /// <returns></returns>
        public bool EnableIOCapture(HikVision cameraParam, bool enable, bool newAlarm = true)
        {
            if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
            {
                return false;
            }

            bool result = false;
            try
            {
                result = HikVisionDll.KsCamera_HC_EnableIOCapture(cameraParam.LoginId, newAlarm, enable);
            }
            catch (Exception e)
            {
                throw new CameraException("使能IO报警失败", e.Message);
            }

            return result;
        }

        /// <summary>
        /// 获取IO报警抓拍图片
        /// </summary>
        /// <param name="nCaptureId"></param>
        /// <param name="ioAlarmCapture"></param>
        /// <returns></returns>
        public static bool GetIOAlarmCaptureImage(int nCaptureId, ref HikIOAlarmCapture ioAlarmCapture)
        {
            try
            {
                return HikVisionDll.KsCamera_HC_GetIOAlarmCaptureImage(nCaptureId, ref ioAlarmCapture);
            }
            catch (Exception e)
            {
                throw new CameraException("获取IO报警抓拍图片失败", e.Message);
            }
        }

        /// <summary>
        /// 手动触发IO报警抓拍
        /// </summary>
        /// <param name="cameraParam"></param>
        /// <param name="nRoadNo"></param>
        /// <param name="nSnapTimes"></param>
        /// <param name="nSnapWaitTime"></param>
        /// <param name="nIntervalTime"></param>
        /// <returns></returns>
        public bool ManualIOAlarmCapture(HikVision cameraParam, byte nRoadNo, byte nSnapTimes, short nSnapWaitTime, short nIntervalTime)
        {
            if (HikVision.DefaultDeviceHandle == cameraParam.LoginId)
            {
                return false;
            }

            return HikVisionDll.KsCamera_HC_ManualIOAlarmCapture(cameraParam.LoginId, nRoadNo, nSnapTimes, nSnapWaitTime, nIntervalTime);
        }
    }
}
